<?php
namespace App\Repositories\Home;

use App\Models\Attendance;
use App\Models\Department;
use App\Models\User;
use App\Models\WorkTime;
use App\Repositories\Attendance\AttendanceRepository;
use Carbon\Carbon;

class HomeDBRepository implements HomeRepository
{

    public function getClendError(HomeFilter $homeFilter)
    {
        $workQuery = WorkTime::query();

        $startTime = $homeFilter->getStartTime();
        $endTime = $homeFilter->getEndTime();
        if ($startTime && $endTime) {
            $workQuery->where('start_time', '>=', $startTime. ' 00:00:00')
                ->where('start_time', '<=', $endTime. ' 23:00:00');
        }

        $work = $workQuery->get()->toArray();

        $attendances = [];

        foreach ($work as $v) {
            $attendanceQuery = Attendance::query();
            $res = $attendanceQuery->where('register_time','like', '%'. substr($v['start_time'], 0, 10). '%')->get();
            $defineAttendance = (float)((strtotime($v['end_time'])-strtotime($v['start_time']))%86400/3600);
            $res->groupBy(function ($item) {
                return $item['attendance_no'].'|'.$item['name'];
            })->map(function ($item) use (&$attendances, $defineAttendance, $v){
                $att = new Attendance();
                $sortRes = $item->sortBy('register_time');
                $startTime = $sortRes->first();
                $endTime = $sortRes->pop();

                $att['name'] = $startTime->name;
                $att['department_name'] = User::where('name',$startTime->name)->where('attendance_no', $startTime->attendance_no)->first()->department->name;
                $att['start_time'] = $startTime->register_time;
                $att['end_time'] = $endTime->register_time;
                $minute=(float)((strtotime($att['end_time'])-strtotime($att['start_time']))%86400/3600);
                $att['total_time'] = round($minute,1);
                $att['time'] = substr($v['start_time'], 0, 10);

                if ($minute < $defineAttendance) {
                    $attendances[] = $att;
                }
            });
        }

        $att = collect($attendances)->groupBy('time');

        $atten = [];
        $att->map(function ($item, $key) use(&$atten){
            $temp = [];
            $temp['date'] = $key;
            $temp['count'] = $item->count();
            $temp['data'] = $item;
            $atten[] = $temp;
        });

        return $atten;
    }

    public function getAttendance(HomeFilter $homeFilter)
    {
        $startTime = Carbon::parse(Carbon::parse('-7 days')->toDateString())->toDateTimeString();
        $endTime = Carbon::today()->toDateTimeString();

        $work = WorkTime::where('start_time', '>=', $startTime. ' 00:00:00')
            ->where('start_time', '<=', $endTime. ' 23:00:00')->get()->toArray();

        $att = [];
        foreach ($work as $v) {
            Department::with('users')->get()->map(function ($item) use($v, &$att){
                $tempAtt = [];
                $tempAtt['time'] = substr($v['start_time'], 0, 10);
                $userCount =  $item->users->count();
                $totalWorkTiem = 0;
                $tempAtt['department_name'] = $item->name;
                $item->users->map(function($val) use (&$totalWorkTiem, $v){
                    $attendce = Attendance::where('attendance_no', $val->attendance_no)
                        ->where('name', $val->name)
                        ->where('register_time','like', '%'. substr($v['start_time'], 0, 10). '%')
                        ->get();
                    if (!$attendce->isEmpty()){
                        $sortRes = $attendce->sortBy('register_time');
                        $startTime = $sortRes->first();
                        $endTime = $sortRes->pop();
                        $totalWorkTiem += round((float)((strtotime($endTime->register_time)-strtotime($startTime->register_time))%86400/3600),1);
                    }
                });
                if ($userCount == 0){
                    $tempAtt['percent'] = 0;
                }else{
                    $tempAtt['percent'] = round($totalWorkTiem/$userCount,1);
                }

                $att[] = $tempAtt;
            });
        }
        return $att;
    }

    public function getSevenTotal(HomeFilter $homeFilter)
    {
        $startTime = Carbon::parse(Carbon::parse('-7 days')->toDateString())->toDateTimeString();
        $endTime = Carbon::today()->toDateTimeString();

        $work = WorkTime::where('start_time', '>=', $startTime. ' 00:00:00')
            ->where('start_time', '<=', $endTime. ' 23:00:00')->get()->toArray();

        $att = [];
        $att['users'] = [];
        User::query()->whereNotNull('teambition_sign')->get()->map(function($item) use ($work, &$att){
            $defineAttendanceTimes = 0;
            $users['total'] = 0;
            $users['name'] = $item->name;
            foreach ($work as $v) {
                $defineAttendance = rand((float)((strtotime($v['end_time'])-strtotime($v['start_time']))%86400/3600),1);
                if ($v['work_type'] == 1){
                    $defineAttendanceTimes += $defineAttendance;
                }
                $res = Attendance::where('register_time','like', '%'. substr($v['start_time'], 0, 10). '%')
                    ->where('name', $item->name)
                    ->where('attendance_no', $item->attendance_no)
                    ->get();
                if (!$res->isEmpty()) {
                    $sortRes = $res->sortBy('register_time');
                    $startTime = $sortRes->first();
                    $endTime = $sortRes->pop();
                    $minute=(float)((strtotime($endTime->register_time)-strtotime($startTime->register_time))%86400/3600);
                    $users['total'] += round($minute,1);
                }
            }
            $att['total'] = $defineAttendanceTimes;
            $att['users'][] = $users;
        });
        $users = collect($att['users']);

        if ($homeFilter->getSort() == 'asc') {
            $att['users'] = $users->sortBy('total')->values()->toArray();
        }

        if ($homeFilter->getSort() == 'desc') {
            $att['users'] = $users->sortByDesc('total')->values()->toArray();
        }
        return $att;

    }

    public function getSevenTotalDepartment(HomeFilter $homeFilter)
    {

        $startTime = Carbon::parse(Carbon::parse('-7 days')->toDateString())->toDateTimeString();
        $endTime = Carbon::today()->toDateTimeString();

        $work = WorkTime::where('start_time', '>=', $startTime. ' 00:00:00')
            ->where('start_time', '<=', $endTime. ' 23:00:00')->get()->toArray();

        $att = [];
            Department::with('users')->get()->map(function ($item) use(&$att, $work){
                $tempAtt = [];
                $totalWorkTiem = 0;
                $defineAttendanceTimes = 0;
                $tempAtt['department_name'] = $item->name;
                foreach ($work as $v){

                    if ($v['work_type'] == 1){
                        $defineAttendance = rand((float)((strtotime($v['end_time'])-strtotime($v['start_time']))%86400/3600),1);
                        $defineAttendanceTimes += $defineAttendance;
                    }
                    $item->users->map(function ($val) use (&$totalWorkTiem, $v) {
                        $attendce = Attendance::where('attendance_no', $val->attendance_no)
                            ->where('name', $val->name)
                            ->where('register_time', 'like', '%' . substr($v['start_time'], 0, 10) . '%')
                            ->get();
                        if (!$attendce->isEmpty()) {
                            $sortRes = $attendce->sortBy('register_time');
                            $startTime = $sortRes->first();
                            $endTime = $sortRes->pop();
                            $totalWorkTiem += round((float)((strtotime($endTime->register_time) - strtotime($startTime->register_time)) % 86400 / 3600), 1);
                        }
                    });
                }
                $tempAtt['total'] = round($totalWorkTiem,1);
                $att['departments'][] = $tempAtt;
                $att['total'] = $defineAttendanceTimes;
            });
            $att['departments'] = collect($att['departments'])->sortByDesc('total')->values()->toArray();

        return $att;
    }
}
